//Francisco "Kiko" Olvera
//holds array of 50 tiles total
//board consists of a 2D array of tile pointers
//keeps track of current and extra tiles at all times
//Board.h

#include "Board.h"
#include "Artifact.h"
#include "ENUM.h"
#include "DirectX.h"
#include "Clock.h"
#include "Player.h"
#include <stdlib.h>
extern int g_CamPos;

Board::Board()
{
}

void Board::Init(Artifact* a_artifacts)
{
	artifact = a_artifacts;
	//load the three tiles meshes
	straightMesh.Load("Assets/Models/STRAIGHT_Tile_Piece.x");
	elbowMesh.Load("Assets/Models/ELBOW_Tile_Piece.x");
	threewayMesh.Load("Assets/Models/THREEWAY_Tile_Piece.x");
	spawnTiles();
	//seed rand before filling board for first time
	srand((unsigned int)Clock::instance()->getCurrentTime());
	fillBoard();
	extraPos = TOP1;

	//make light point to # new lights in the heap
	light = new Light[NUM_OF_LIGHTS];
	//need to init light after players have been initialized
	//initLight();
}

void Board::spawnTiles()
{
	//first 4 are spawn points
	tile[0].setSpawn(ELBOW, XY(0,0), NORTH);
	tile[1].setSpawn(ELBOW, XY(LAST_IN_ROW_OR_COLUMN,0), EAST);
	tile[2].setSpawn(ELBOW, XY(LAST_IN_ROW_OR_COLUMN,LAST_IN_ROW_OR_COLUMN), SOUTH);
	tile[3].setSpawn(ELBOW, XY(0,LAST_IN_ROW_OR_COLUMN), WEST);
	for(int i=0;i<NUM_PLAYERS;++i)
		placeTile(&tile[i], i);

	int counter=NUM_PLAYERS;

	//12 straight pieces
	for(int i=0;i<NUM_STRAIGHT;++i, counter++)
		tile[counter].setType(STRAIGHT);
	//16 elbows
	for(int i=0;i<NUM_ELBOW;++i, counter++)
		tile[counter].setType(ELBOW);
	//18 threeway
	for(int i=0;i<NUM_THREEWAY;++i, counter++)
		tile[counter].setType(THREEWAY);

	//threeway immovable peices
	tile[38].setSpawn(THREEWAY, XY(2,0), SOUTH);
	tile[39].setSpawn(THREEWAY, XY(4,0), SOUTH);
	tile[40].setSpawn(THREEWAY, XY(0,2), EAST);
	tile[41].setSpawn(THREEWAY, XY(2,2), EAST);
	tile[42].setSpawn(THREEWAY, XY(4,2), SOUTH);
	tile[43].setSpawn(THREEWAY, XY(6,2), WEST);
	tile[44].setSpawn(THREEWAY, XY(0,4), EAST);
	tile[45].setSpawn(THREEWAY, XY(2,4), NORTH);
	tile[46].setSpawn(THREEWAY, XY(4,4), WEST);
	tile[47].setSpawn(THREEWAY, XY(6,4), WEST);
	tile[48].setSpawn(THREEWAY, XY(2,6), NORTH);
	tile[49].setSpawn(THREEWAY, XY(4,6), NORTH);
	for(int i=38;i<NUM_TILES;++i)
		placeTile(&tile[i], i);
	
	placeArtifacts();
	
	int count = 1;

	//swap
	tile[NUM_STRAIGHT-count].setPower(&swap);
	tile[NUM_STRAIGHT+NUM_ELBOW-count].setPower(&swap);

	count++;

	//search
	tile[NUM_STRAIGHT-count].setPower(&searchForCard);
	tile[NUM_STRAIGHT+NUM_ELBOW-count].setPower(&searchForCard);

	count++;

	//shift
	tile[NUM_STRAIGHT-count].setPower(&ShiftExTile);
	tile[NUM_STRAIGHT+NUM_ELBOW-count].setPower(&ShiftExTile);

	count++;

	//turn
	tile[NUM_STRAIGHT-count].setPower(&ExTurn);
	tile[NUM_STRAIGHT+NUM_ELBOW-count].setPower(&ExTurn);

	count++;

	//rotate
	tile[NUM_STRAIGHT-count].setPower(&rotate);
	tile[NUM_STRAIGHT+NUM_ELBOW-count].setPower(&rotate);

	count++;

	//pass wall is still OP
	//tile[NUM_STRAIGHT-count].setPower(&wallPass);
	//tile[NUM_STRAIGHT+NUM_ELBOW-count].setPower(&wallPass);
	//cannot debug sound
	//for(int i=0;i<NUM_TILES;++i)
	//	tile[i].setPower(&wallPass);
}

//place artifacts on appropriate tiles
void Board::placeArtifacts()
{
	int c, counter = NUM_PLAYERS + NUM_STRAIGHT;

	//some elbow pieces have artifacts
	for(c=0;c<NUM_ELBOW_ARTS;++c, counter++)
		tile[counter].setArtifact(&artifact[c]);

	//all 3-way pieces have artifacts
	counter = NUM_PLAYERS + NUM_STRAIGHT + NUM_ELBOW;
	for(counter;counter<NUM_TILES;++c, counter++)
		tile[counter].setArtifact(&artifact[c]);
}

//make the tile's position in the 2D array "map" match its boardPos variable
void Board::placeTile(Tile* pTile, int num)
{
	XY pos = pTile->getBoardPos();
	map[pos.X][pos.Y] = &tile[num];
}

void Board::pickTile(int X, int Y)
{
	//pick random tile between 4 and 37
	int num = (rand()%TILE_PICK_RAND_MAX) + NUM_PLAYERS;
	//that has not already picked
	while(picked[num])
		num = (rand()%TILE_PICK_RAND_MAX) + NUM_PLAYERS;
	picked[num] = true;
	map[X][Y] = &tile[num];
	tile[num].setBoardPos(XY(X,Y));
	tile[num].setOrientation(rand()%NUM_DIRECTIONS);
}

void Board::fillBoard()
{
	for(int i=0;i<NUM_TILES;++i)
		picked[i] = false;
	//randomly fill rows
	for(int i=0;i<NUM_ROWS_AND_COLUMNS;++i)
	{
		for(int j=0;j<NUM_ROWS_AND_COLUMNS;++j)
		{
			//odd rows
			if(i%2)
				pickTile(j,i);
			//even rows
			else
			{
				//every other tile is occupied by immovable piece
				if(j%2)
					pickTile(j,i);
			}
		}
	}
	//find the extra piece
	for(int i=NUM_PLAYERS;i<38;++i)
	{
		if(picked[i] == false)
		{
			extra = &tile[i];
			tile[i].setSpawn(tile[i].getType(), XY(-1,-1), NORTH);
			tile[i].setMovable(true);
			break;
		}
	}
	//start with player one
	currentTile = map[0][0];
}
//init light(s)
void Board::initLight(int aNumOfPlayers, int * aOrder, Player * aPlayers)
{
	/************************
	*** Will's light code ***
	*************************/
	for(int i = 0; i < NUM_OF_LIGHTS; ++i)
	{
		light[i].setLightType(POINT_LIGHT);
		light[i].setAmbientLight(1.0f, 1.0f, 1.0f, 1.0f);
		light[i].setDiffuseLight(1.0f, 1.0f, 1.0f, 1.0f);
		light[i].setRange(999.0f);
	}
	XY boardPos;
	//lights should initialize in order player colors get initialized
	for(int i = 0; i < aNumOfPlayers; ++i)
	{
		switch(aOrder[i])
		{
		//blue
		case 0:	
			{
				light[i].setSpecularLight(0.0f, 0.0f, 0.5f, 1.0f);
				boardPos = aPlayers[i].getCurrentTile()->getBoardPos();
				light[i].setPosition(boardPos.X*TILE_SIZE, light[i].getRange()+1,boardPos.Y*-TILE_SIZE);
			}
		break;
		//red
		case 1:	
			{
				light[i].setSpecularLight(0.5f, 0.0f, 0.0f, 1.0f);	
				boardPos = aPlayers[i].getCurrentTile()->getBoardPos();
				light[i].setPosition(boardPos.X*TILE_SIZE, light[i].getRange()+1,boardPos.Y*-TILE_SIZE);
			}
			break;
		//yellow
		case 2:	
			{
				light[i].setSpecularLight(0.5f, 0.5f, 0.0f, 1.0f);	
				boardPos = aPlayers[i].getCurrentTile()->getBoardPos();
				light[i].setPosition(boardPos.X*TILE_SIZE, light[i].getRange()+1,boardPos.Y*-TILE_SIZE);
			}
			break;
		//green
		case 3:	
			{
				light[i].setSpecularLight(0.0f, 0.5f, 0.0f, 1.0f);	
				boardPos = aPlayers[i].getCurrentTile()->getBoardPos();
				light[i].setPosition(boardPos.X*TILE_SIZE, light[i].getRange()+1,boardPos.Y*-TILE_SIZE);
			}
			break;
		}
		//enable and send light to device
		light[i].setLightToDevice(i);
		light[i].enableLight(i, true);
	}

	//initializes rest of lights to white and proper corners of the board
	//when number of players is less than 4
	if(aNumOfPlayers < NUM_OF_LIGHTS-1)
	{
		int difference = (NUM_OF_LIGHTS-1) - aNumOfPlayers;
		//since we're not holding onto tile positions
		//i have to init light positions based on special cases
		//determined by the amount of players there are
		if(aNumOfPlayers == 2)
		{
			boardPos = aPlayers[1].getCurrentTile()->getBoardPos();
			light[2].setPosition(boardPos.X*TILE_SIZE,1000.0f,boardPos.X*-TILE_SIZE);
			light[3].setPosition(0.0f, 1000.0f, boardPos.X*-TILE_SIZE);
		}
		else //number of players is 3
		{
			boardPos = aPlayers[2].getCurrentTile()->getBoardPos();
			light[3].setPosition(0.0f, 1000.0f, boardPos.X*-TILE_SIZE);
		}
		//set rest of lights spec color to white, enable it, and pass it to device
		for(int i = (NUM_OF_LIGHTS-1)-difference; i < NUM_OF_LIGHTS; ++i)
		{
			//white light
			light[i].setSpecularLight(0.5f, 0.5f, 0.5f, 1.0f);
			light[i].setLightToDevice(i);
			light[i].enableLight(i, true);
		}
	}
	//always make last light white and centered on board
	//white light
	light[NUM_OF_LIGHTS-1].setSpecularLight(0.5f, 0.5f, 0.5f, 1.0f);	
	light[NUM_OF_LIGHTS-1].setPosition(300.0f,1000.0f,-300.0f);
	light[NUM_OF_LIGHTS-1].setLightToDevice(4);
	light[NUM_OF_LIGHTS-1].enableLight(4, true);
}
//make all tiles boardPos match placement in 2D array
void Board::secureTilePositions()
{
	for(int i=0;i<NUM_ROWS_AND_COLUMNS;++i)
	{
		for(int j=0;j<NUM_ROWS_AND_COLUMNS;++j)
		{
			map[j][i]->setBoardPos(XY(j,i));
		}
	}
}

void Board::Render()
{
	for(int i=0;i<NUM_ROWS_AND_COLUMNS;++i)
	{
		for(int j=0;j<NUM_ROWS_AND_COLUMNS;++j)
		{
			//draw every tile with the appropriate mesh and direction
			Tile* tile = map[j][i];
			int tType = tile->getType();
			int direction = tile->getOrientation();
			DirectXFramework::Instance()->getDevice()->SetMaterial(&tile->getMaterial());
			switch(tType)
			{
			case STRAIGHT:
				straightMesh.Draw(j*TILE_SIZE, -i*TILE_SIZE, direction);
				break;
			case ELBOW:
				elbowMesh.Draw(j*TILE_SIZE, -i*TILE_SIZE, direction);
				break;
			case THREEWAY:
				threewayMesh.Draw(j*TILE_SIZE, -i*TILE_SIZE, direction);
				break;
			};
			Artifact* pArt = tile->getArtifact();
			if(pArt)
			{
				DirectXFramework::Instance()->getDevice()->SetMaterial(&pArt->getMaterial());
				pArt->Draw(j*TILE_SIZE, -i*TILE_SIZE);
			}
		}
	}
	DrawExtra();
}

void Board::DrawExtra()
{
	int type = extra->getType();
	int direction = extra->getOrientation();
	//draw extra tile
	switch(extraPos)
	{
	case TOP1:
		switch(type)
		{
		case STRAIGHT:
			straightMesh.Draw(TILE_SIZE, TILE_SIZE+EXTRA_TILE_DIST, direction);
			break;
		case ELBOW:
			elbowMesh.Draw(TILE_SIZE, TILE_SIZE+EXTRA_TILE_DIST, direction);
			break;
		case THREEWAY:
			threewayMesh.Draw(TILE_SIZE, TILE_SIZE+EXTRA_TILE_DIST, direction);
			break;
		};
		break;
	case TOP3:
		switch(type)
		{
		case STRAIGHT:
			straightMesh.Draw(TILE_SIZE*3.0f, TILE_SIZE+EXTRA_TILE_DIST, direction);
			break;
		case ELBOW:
			elbowMesh.Draw(TILE_SIZE*3.0f, TILE_SIZE+EXTRA_TILE_DIST, direction);
			break;
		case THREEWAY:
			threewayMesh.Draw(TILE_SIZE*3.0f, TILE_SIZE+EXTRA_TILE_DIST, direction);
			break;
		};
		break;
	case TOP5:
		switch(type)
		{
		case STRAIGHT:
			straightMesh.Draw(TILE_SIZE*5.0f, TILE_SIZE+EXTRA_TILE_DIST, direction);
			break;
		case ELBOW:
			elbowMesh.Draw(TILE_SIZE*5.0f, TILE_SIZE+EXTRA_TILE_DIST, direction);
			break;
		case THREEWAY:
			threewayMesh.Draw(TILE_SIZE*5.0f, TILE_SIZE+EXTRA_TILE_DIST, direction);
			break;
		};
		break;
	case RIGHT1:
		switch(type)
		{
		case STRAIGHT:
			straightMesh.Draw((TILE_SIZE*NUM_ROWS_AND_COLUMNS)+EXTRA_TILE_DIST, -TILE_SIZE, direction);
			break;
		case ELBOW:
			elbowMesh.Draw((TILE_SIZE*NUM_ROWS_AND_COLUMNS)+EXTRA_TILE_DIST, -TILE_SIZE, direction);
			break;
		case THREEWAY:
			threewayMesh.Draw((TILE_SIZE*NUM_ROWS_AND_COLUMNS)+EXTRA_TILE_DIST, -TILE_SIZE, direction);
			break;
		};
		break;
	case RIGHT3:
		switch(type)
		{
		case STRAIGHT:
			straightMesh.Draw((TILE_SIZE*NUM_ROWS_AND_COLUMNS)+EXTRA_TILE_DIST, -TILE_SIZE*3.0f, direction);
			break;
		case ELBOW:
			elbowMesh.Draw((TILE_SIZE*NUM_ROWS_AND_COLUMNS)+EXTRA_TILE_DIST, -TILE_SIZE*3.0f, direction);
			break;
		case THREEWAY:
			threewayMesh.Draw((TILE_SIZE*NUM_ROWS_AND_COLUMNS)+EXTRA_TILE_DIST, -TILE_SIZE*3.0f, direction);
			break;
		};
		break;
	case RIGHT5:
		switch(type)
		{
		case STRAIGHT:
			straightMesh.Draw((TILE_SIZE*NUM_ROWS_AND_COLUMNS)+EXTRA_TILE_DIST, -TILE_SIZE*5.0f, direction);
			break;
		case ELBOW:
			elbowMesh.Draw((TILE_SIZE*NUM_ROWS_AND_COLUMNS)+EXTRA_TILE_DIST, -TILE_SIZE*5.0f, direction);
			break;
		case THREEWAY:
			threewayMesh.Draw((TILE_SIZE*NUM_ROWS_AND_COLUMNS)+EXTRA_TILE_DIST, -TILE_SIZE*5.0f, direction);
			break;
		};
		break;
	case BOTTOM1:
		switch(type)
		{
		case STRAIGHT:
			straightMesh.Draw(TILE_SIZE, -(TILE_SIZE*NUM_ROWS_AND_COLUMNS)-EXTRA_TILE_DIST, direction);
			break;
		case ELBOW:
			elbowMesh.Draw(TILE_SIZE, -(TILE_SIZE*NUM_ROWS_AND_COLUMNS)-EXTRA_TILE_DIST, direction);
			break;
		case THREEWAY:
			threewayMesh.Draw(TILE_SIZE, -(TILE_SIZE*NUM_ROWS_AND_COLUMNS)-EXTRA_TILE_DIST, direction);
			break;
		};
		break;
	case BOTTOM3:
		switch(type)
		{
		case STRAIGHT:
			straightMesh.Draw(TILE_SIZE*3.0f, -(TILE_SIZE*NUM_ROWS_AND_COLUMNS)-EXTRA_TILE_DIST, direction);
			break;
		case ELBOW:
			elbowMesh.Draw(TILE_SIZE*3.0f, -(TILE_SIZE*NUM_ROWS_AND_COLUMNS)-EXTRA_TILE_DIST, direction);
			break;
		case THREEWAY:
			threewayMesh.Draw(TILE_SIZE*3.0f, -(TILE_SIZE*NUM_ROWS_AND_COLUMNS)-EXTRA_TILE_DIST, direction);
			break;
		};
		break;
	case BOTTOM5:
		switch(type)
		{
		case STRAIGHT:
			straightMesh.Draw(TILE_SIZE*5.0f, -(TILE_SIZE*NUM_ROWS_AND_COLUMNS)-EXTRA_TILE_DIST, direction);
			break;
		case ELBOW:
			elbowMesh.Draw(TILE_SIZE*5.0f, -(TILE_SIZE*NUM_ROWS_AND_COLUMNS)-EXTRA_TILE_DIST, direction);
			break;
		case THREEWAY:
			threewayMesh.Draw(TILE_SIZE*5.0f, -(TILE_SIZE*NUM_ROWS_AND_COLUMNS)-EXTRA_TILE_DIST, direction);
			break;
		};
		break;
	case LEFT1:
		switch(type)
		{
		case STRAIGHT:
			straightMesh.Draw(-TILE_SIZE-EXTRA_TILE_DIST, -TILE_SIZE, direction);
			break;
		case ELBOW:
			elbowMesh.Draw(-TILE_SIZE-EXTRA_TILE_DIST, -TILE_SIZE, direction);
			break;
		case THREEWAY:
			threewayMesh.Draw(-TILE_SIZE-EXTRA_TILE_DIST, -TILE_SIZE, direction);
			break;
		};
		break;
	case LEFT3:
		switch(type)
		{
		case STRAIGHT:
			straightMesh.Draw(-TILE_SIZE-EXTRA_TILE_DIST, -TILE_SIZE*3.0f, direction);
			break;
		case ELBOW:
			elbowMesh.Draw(-TILE_SIZE-EXTRA_TILE_DIST, -TILE_SIZE*3.0f, direction);
			break;
		case THREEWAY:
			threewayMesh.Draw(-TILE_SIZE-EXTRA_TILE_DIST, -TILE_SIZE*3.0f, direction);
			break;
		};
		break;
	case LEFT5:
		switch(type)
		{
		case STRAIGHT:
			straightMesh.Draw(-TILE_SIZE-EXTRA_TILE_DIST, -TILE_SIZE*5.0f, direction);
			break;
		case ELBOW:
			elbowMesh.Draw(-TILE_SIZE-EXTRA_TILE_DIST, -TILE_SIZE*5.0f, direction);
			break;
		case THREEWAY:
			threewayMesh.Draw(-TILE_SIZE-EXTRA_TILE_DIST, -TILE_SIZE*5.0f, direction);
			break;
		};
		break;
	};
}

void Board::setCurrentTile(XY newPos)
{
	currentTile = map[newPos.X][newPos.Y];
}

void Board::RotateExtraTileClock()
{
	int direction = extra->getOrientation();
	direction++;
	if(direction > WEST)
		direction = NORTH;
	extra->setOrientation(direction);
}

void Board::RotateExtraTileCounterClock()
{
	int direction = extra->getOrientation();
	direction--;
	if(direction < 0)
		direction = WEST;
	extra->setOrientation(direction);
}

Tile* Board::getRealNorth()
{
	XY pos = currentTile->getBoardPos();
	if(pos.Y == 0)
		return NULL;
	else
		return map[pos.X][pos.Y-1];
}

Tile* Board::getRealSouth()
{
	XY pos = currentTile->getBoardPos();
	if(pos.Y == LAST_IN_ROW_OR_COLUMN)
		return NULL;
	else
		return map[pos.X][pos.Y+1];
}

Tile* Board::getRealEast()
{
	XY pos = currentTile->getBoardPos();
	if(pos.X == LAST_IN_ROW_OR_COLUMN)
		return NULL;
	else
		return map[pos.X+1][pos.Y];
}

Tile* Board::getRealWest()
{
	XY pos = currentTile->getBoardPos();
	if(pos.X == 0)
		return NULL;
	else
		return map[pos.X-1][pos.Y];
}

//Neighbor Checking
Tile* Board::getN()
{
	switch(g_CamPos)
	{
	case CAM_NORTH:	return getRealSouth();
	case CAM_SOUTH:	return getRealNorth();
	case CAM_EAST:	return getRealWest();
	case CAM_WEST:	return getRealEast();
	}
	return NULL;
}

Tile* Board::getS()
{
	switch(g_CamPos)
	{
	case CAM_NORTH:	return getRealNorth();
	case CAM_SOUTH:	return getRealSouth();
	case CAM_EAST:	return getRealEast();
	case CAM_WEST:	return getRealWest();
	}
	return NULL;
}

Tile* Board::getE()
{
	switch(g_CamPos)
	{
	case CAM_NORTH:	return getRealWest();
	case CAM_SOUTH:	return getRealEast();
	case CAM_EAST:	return getRealNorth();
	case CAM_WEST:	return getRealSouth();
	}
	return NULL;
}

Tile* Board::getW()
{
	switch(g_CamPos)
	{
	case CAM_NORTH:	return getRealEast();
	case CAM_SOUTH:	return getRealWest();
	case CAM_EAST:	return getRealSouth();
	case CAM_WEST:	return getRealNorth();
	}
	return NULL;
}

//column/row shifting
Tile* Board::shiftColumnDown(int column)
{
	Tile* temp;
	temp = map[column][LAST_IN_ROW_OR_COLUMN];
	if(currentTile == temp)
		currentTile = extra;
	for(int i=LAST_IN_ROW_OR_COLUMN; i>0; --i)
	{
		map[column][i] = map[column][i-1];
	}
	map[column][0] = extra;
	Tile* newt = extra;
	extra = temp;
	secureTilePositions();
	return newt;
}

Tile* Board::shiftColumnUp(int column)
{
	Tile* temp;
	temp = map[column][0];
	if(currentTile == temp)
		currentTile = extra;
	for(int i=0;i<LAST_IN_ROW_OR_COLUMN;++i)
	{
		map[column][i] = map[column][i+1];
	}
	map[column][LAST_IN_ROW_OR_COLUMN] = extra;
	Tile* newt = extra;
	extra = temp;
	secureTilePositions();
	return newt;
}

Tile* Board::shiftRowLeft(int row)
{
	Tile* temp;
	temp = map[0][row];
	if(currentTile == temp)
		currentTile = extra;
	for(int i=0;i<LAST_IN_ROW_OR_COLUMN;++i)
	{
		map[i][row] = map[i+1][row];
	}
	map[LAST_IN_ROW_OR_COLUMN][row] = extra;
	Tile* newt = extra;
	extra = temp;
	secureTilePositions();
	return newt;
}

Tile* Board::shiftRowRight(int row)
{
	Tile* temp;
	temp = map[LAST_IN_ROW_OR_COLUMN][row];
	if(currentTile == temp)
		currentTile = extra;
	for(int i=LAST_IN_ROW_OR_COLUMN;i>0;--i)
	{
		map[i][row] = map[i-1][row];
	}
	map[0][row] = extra;
	Tile* newt = extra;
	extra = temp;
	secureTilePositions();
	return newt;
}

Tile* Board::boardShift()
{
	int lastPos = extraPos;
	ExtraTileOut();
	switch(lastPos)
	{
	case TOP1:
		return shiftColumnDown(1);
	case TOP3:
		return shiftColumnDown(3);
	case TOP5:
		return shiftColumnDown(5);
	case RIGHT1:
		return shiftRowLeft(1);
	case RIGHT3:
		return shiftRowLeft(3);
	case RIGHT5:
		return shiftRowLeft(5);
		break;
	case BOTTOM5:
		return shiftColumnUp(5);
	case BOTTOM3:
		return shiftColumnUp(3);
	case BOTTOM1:
		return shiftColumnUp(1);
	case LEFT5:
		return shiftRowRight(5);
		break;
	case LEFT3:
		return shiftRowRight(3);
	case LEFT1:
		return shiftRowRight(1);
	};
	return currentTile;
}

void Board::ExtraTileOut()
{
	switch(extraPos)
	{
	case TOP1:
		extraPos = BOTTOM1;
		break;
	case TOP3:
		extraPos = BOTTOM3;
		break;
	case TOP5:
		extraPos = BOTTOM5;
		break;
	case RIGHT1:
		extraPos = LEFT1;
		break;
	case RIGHT3:
		extraPos = LEFT3;
		break;
	case RIGHT5:
		extraPos = LEFT5;
		break;
	case BOTTOM5:
		extraPos = TOP5;
		break;
	case BOTTOM3:
		extraPos = TOP3;
		break;
	case BOTTOM1:
		extraPos = TOP1;
		break;
	case LEFT5:
		extraPos = RIGHT5;
		break;
	case LEFT3:
		extraPos = RIGHT3;
		break;
	case LEFT1:
		extraPos = RIGHT1;
		break;
	};
}

void Board::Update(Input * apInput)
{
	for(int i = 0; i < NUM_OF_LIGHTS; ++i)
	{
		light[i].Update(apInput, i);
	}
	for(int i = 0; i < NUM_ARTIFACTS; ++i)
	{
		artifact[i].alterMatColors();
	}
}
Board::~Board()
{
}